# Pablo Rincon Crespo (C) 2009
# This code is published under the GPL 2 License Terms

import socket
import struct
try:
	from scapy.all import *
except:
	try:
		from scapy import *
	except:
		print "Error. Scapy Not Found. apt-get install scapy python-scapy"

from NMUtils import *

class NMAction:
	def __init__(self):
		pass
	def perform(self):
		pass

class NMActionForward(NMAction):
	def __init__(self,ifto):
		logger.debug("Created Action forward to " + ifto)
		self.ifto=ifto

	def perform(self,p):
		try:
			logger.debug("Sending to " + str(self.ifto))
			conf.verb=0
			sendp(p,iface=self.ifto, verbose=0)
		except :
		 	logger.error("Error in NMActionForward.perform: error forwarding to "+ self.ifto+". ")
			exit(30)

class NMActionFileWrite(NMAction):
	def __init__(self,file):
		self.file=file
		self.pw=PcapWriter(file)
		logger.debug("Created Action write to file " + file)
			
	def perform(self,p):
		try:
			conf.verb=0
			self.pw.write(p)
		except :
			logger.error("Error NMActionFileWrite.perform: Error writing packet to file "+self.file)

class NMActionResend(NMAction):

	def __init__(self, dst, dport, iface=None, crypt=None):
		logger.debug("Created Action resend to " + dst+ " port "+ dport)
		self.dst=dst
		self.dport=int(dport)
		self.iface=iface
		self.crypt=crypt	
		self.MIRROR_MAGIC=0xcabecafe
		self.connected=False

	def tryconnect(self):
		self.skt=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
		try:
			self.skt.connect((self.dst,self.dport))
			self.connected=True
		except:
			logger.error("Error. Couldnt connect to "+ self.dst+" on port" +self.dport)
			self.connected=False
			
	def perform(self,p):
		if self.connected==False:
			self.tryconnect()

		if p is not None and len(p)>0 and self.connected==True:
			bf=str(p)
			logger.debug("p len to send = " + str(len(bf)))
			logger.debug("Mirror magic: " + str(self.MIRROR_MAGIC))

			fmt="%ds" %len(bf)
			buff=struct.pack("L"+fmt ,self.MIRROR_MAGIC, bf)
		
			try:
				self.skt.send(buff)
			except:
				logger.error("Error. Couldnt resend packet!")
				self.connected=False
				while self.connected==False:
					self.tryconnect()
					time.sleep(2)
		else:
			logger.error("Failed to resend PACKET " + str(p.display()))
			exit(40)

#Net Mirror (c) 2009 Pablo Rincon Crespo
